package com.xzj.admin.flow.service.impl;

import com.alibaba.fastjson2.JSONObject;
import com.xzj.admin.flow.domain.entity.FlowManager;
import com.xzj.admin.flow.domain.entity.FlowNode;
import com.xzj.admin.flow.domain.entity.FlowNodeEdge;
import com.xzj.admin.flow.domain.entity.FlowNodePort;
import com.xzj.admin.flow.domain.vo.FlowReqVo;
import com.xzj.admin.flow.domain.vo.FlowRespVo;
import com.xzj.admin.flow.domain.vo.edge.FlowEdgeVo;
import com.xzj.admin.flow.domain.vo.node.FlowNodeVo;
import com.xzj.admin.flow.mapper.FlowManagerMapper;
import com.xzj.admin.flow.mapper.FlowNodeMapper;
import com.xzj.admin.flow.service.FlowManagerService;
import com.xzj.common.datasource.domain.PageReq;
import com.xzj.common.datasource.domain.PageResp;
import com.xzj.common.datasource.utils.XzjPageUtil;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * @program: xzj-admin
 * @ClassName: FlowManagerServiceImpl
 * @description: 流程管理;(flow_manager)表服务实现类
 * @author: XiaZunJun
 * @create: 2024-9-27
 */
@Service
public class FlowManagerServiceImpl implements FlowManagerService {
    @Resource
    private FlowManagerMapper flowManagerMapper;

    @Resource
    private FlowNodeMapper flowNodeMapper;

    /**
     * 通过ID查询单条数据
     *
     * @param flowId 主键
     * @return 实例对象
     */
    public FlowManager queryById(String flowId) {
        return flowManagerMapper.queryById(flowId);
    }

    /**
     * 分页查询
     *
     * @param pageReq 分页筛选条件对象
     * @return 查询结果
     */
    public PageResp<FlowManager> pageQuery(PageReq<FlowManager> pageReq) {
        return XzjPageUtil.queryPage(pageReq, flowManager -> flowManagerMapper.queryAllByLimit(flowManager));
    }

    /**
     * 新增数据
     *
     * @param flowManager 实例对象
     * @return 实例对象
     */
    public FlowManager insert(FlowManager flowManager) {
        flowManagerMapper.insert(flowManager);
        return flowManager;
    }

    /**
     * 更新数据
     *
     * @param flowManager 实例对象
     * @return 实例对象
     */
    public FlowManager update(FlowManager flowManager) {
        flowManagerMapper.update(flowManager);
        return flowManager;
    }

    /**
     * 通过主键删除数据
     *
     * @param flowId 主键
     * @return 是否成功
     */
    public boolean deleteById(String flowId) {
        int total = flowManagerMapper.deleteById(flowId);
        return total > 0;
    }

    @Transactional
    @Override
    public void addFlowChart(FlowReqVo flowReqVo) {
        flowNodeMapper.portDeleteByFlowId(flowReqVo.getFlowId());
        flowNodeMapper.deleteEdgeByFlowId(flowReqVo.getFlowId());
        flowNodeMapper.deleteByFlowId(flowReqVo.getFlowId());
        List<JSONObject> flowJsons = flowReqVo.getFlowJsons();
        List<FlowNodeEdge> flowNodeEdges = new ArrayList<>();
        List<FlowNode> flowNodes = new ArrayList<>();
        List<FlowNodePort> flowNodePorts = new ArrayList<>();
        for (JSONObject flowJson : flowJsons) {
            if (flowJson.getString("shape").equals("edge")) {
                FlowNodeEdge flowNodeEdge = flowJson.to(FlowNodeEdge.class);
                flowNodeEdge.setFlowId(flowReqVo.getFlowId());
                flowNodeEdges.add(flowNodeEdge);
            } else {
                FlowNode flowNode = flowJson.to(FlowNode.class);
                flowNode.setFlowId(flowReqVo.getFlowId());
                flowNode.setXCoordinate(flowNode.getPosition().getInteger("x"));
                flowNode.setYCoordinate(flowNode.getPosition().getInteger("y"));
                flowNode.setAttrsImage(flowNode.getAttrs().getJSONObject("image").getString("xlink:href"));
                flowNode.setLabel(flowNode.getAttrs().getJSONObject("text").getString("text"));
                flowNodes.add(flowNode);
                List<FlowNodePort> items = flowNode.getPorts().getJSONArray("items").toList(FlowNodePort.class);
                items.forEach(item -> {
                    item.setNodeId(flowNode.getId());
                });
                flowNodePorts.addAll(items);
            }
        }
        flowNodeMapper.batchInsert(flowNodes);
        flowNodeMapper.edgeBatchInsert(flowNodeEdges);
        flowNodeMapper.portBatchInsert(flowNodePorts);
    }

    @Override
    public FlowRespVo queryFlowChart(String flowId) {
        List<FlowNodeVo> flowNodeVos = flowNodeMapper.queryByFlowId(flowId);
        List<FlowEdgeVo> flowEdgeVos = flowNodeMapper.queryEdgeByFlowId(flowId);
        return FlowRespVo.buildResp(flowNodeVos, flowEdgeVos);
    }
}
